package com.dz.util;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Component
public class OSSCleanTask implements InitializingBean, DisposableBean {

    private static final Logger logger = LoggerFactory.getLogger(OSSCleanTask.class);

    // 注入配置信息而不是硬编码
    @Autowired
    private AliyunOSSProperties aliyunOSSProperties;

    private static final String ACCESS_KEY_ID = "LTAI5tBx6UZ6GoU3CHDYTGaZ";
    private static final String ACCESS_KEY_SECRET = "GjHxNxppkjTGRQImgim7MWE2j0W5Lo";

    private OSS ossClient;

    @Override
    public void afterPropertiesSet() throws Exception {
        String endpoint = aliyunOSSProperties.getEndpoint();
        String bucketName = aliyunOSSProperties.getBucketName();

        // 处理配置中的协议前缀
        if (endpoint.startsWith("https://")) {
            endpoint = endpoint.substring(8);
        } else if (endpoint.startsWith("http://")) {
            endpoint = endpoint.substring(7);
        }

        // 使用标准endpoint格式，而不是bucket.endpoint格式
        String ossEndpoint = "https://" + endpoint;
        ossClient = new OSSClientBuilder()
                .build(ossEndpoint, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
        logger.info("OSS客户端初始化完成，使用endpoint: {}", ossEndpoint);
    }

    @Override
    public void destroy() throws Exception {
        if (ossClient != null) {
            ossClient.shutdown();
            logger.info("OSS客户端已关闭");
        }
    }

    // 每周日凌晨2点执行（星期日为一周的开始）
    @Scheduled(cron = "0 0 2 ? * SUN")
    public void cleanExpiredFiles() {
        logger.info("开始执行OSS文件清理任务: {}", LocalDateTime.now());

        try {
            // 获取所有过期文件列表（以24小时为期限）
            List<String> expiredFiles = getExpiredFiles(24);

            if (!expiredFiles.isEmpty()) {
                logger.info("发现{}个过期文件，开始清理...", expiredFiles.size());

                // 批量删除过期文件
                deleteExpiredFiles(expiredFiles);

                logger.info("成功清理{}个过期文件", expiredFiles.size());
            } else {
                logger.info("未发现过期文件");
            }
        } catch (Exception e) {
            logger.error("执行OSS文件清理任务时发生错误", e);
        }
    }

    /**
     * 获取过期文件列表
     * @param hours 过期小时数
     * @return 过期文件列表
     */
    private List<String> getExpiredFiles(int hours) {
        List<String> expiredFiles = new ArrayList<>();

        try {
            // 计算过期时间
            Date expireDate = Date.from(
                    LocalDateTime.now().minusHours(hours).atZone(ZoneId.systemDefault()).toInstant()
            );

            // 列出所有文件（使用推荐的分页方式）
            String nextMarker = null;
            do {
                ListObjectsRequest listObjectsRequest = new ListObjectsRequest(aliyunOSSProperties.getBucketName());
                listObjectsRequest.setMarker(nextMarker);
                listObjectsRequest.setMaxKeys(1000);

                ObjectListing objectListing = ossClient.listObjects(listObjectsRequest);

                for (OSSObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                    // 如果文件创建时间早于过期时间，则认为是过期文件
                    if (objectSummary.getLastModified().before(expireDate)) {
                        expiredFiles.add(objectSummary.getKey());
                        logger.debug("发现过期文件: {}，创建时间: {}",
                                objectSummary.getKey(), objectSummary.getLastModified());
                    }
                }

                nextMarker = objectListing.getNextMarker();
            } while (nextMarker != null);

        } catch (Exception e) {
            logger.error("获取过期文件列表时发生错误", e);
        }

        return expiredFiles;
    }

    // 批量删除过期文件
    private void deleteExpiredFiles(List<String> expiredFiles) {
        try {
            // 分批删除（OSS限制每次最多删除1000个文件）
            int batchSize = 1000;
            for (int i = 0; i < expiredFiles.size(); i += batchSize) {
                int endIndex = Math.min(i + batchSize, expiredFiles.size());
                List<String> batch = expiredFiles.subList(i, endIndex);

                DeleteObjectsRequest deleteObjectsRequest = new DeleteObjectsRequest(aliyunOSSProperties.getBucketName());
                deleteObjectsRequest.setKeys(batch);
                ossClient.deleteObjects(deleteObjectsRequest);

                logger.info("已删除{}个文件", batch.size());
            }
        } catch (Exception e) {
            logger.error("删除过期文件时发生错误", e);
        }
    }
}
